package com.example.composableexample.textfield

import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Card
import androidx.compose.material.Icon
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.SliderDefaults
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.rounded.AttachMoney
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.MaterialTheme
import androidx.compose.material.Slider
import androidx.compose.material.icons.filled.Remove
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.example.composableexample.ui.theme.ComposableExampleTheme


@Preview
@Composable
fun Tipper() {
    ComposableExampleTheme {
        Surface(color = Color.White, modifier = Modifier.fillMaxSize()) {
            Column {
                MainContent()
            }
        }
    }
}

@Composable
fun MainContent() {
    val splitNumber = remember {
        mutableStateOf(2)
    }
    val tipAmount = remember {
        mutableStateOf(0.0)
    }
    val totalPerPerson = remember {
        mutableStateOf(0.0)
    }
    Column(modifier = Modifier.padding(16.dp)) {
        Tipper(
            splitNumber = splitNumber,
            tipAmount = tipAmount,
            totalPerPerson = totalPerPerson,
            onValueChange = {}
        )
    }
}

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun Tipper(
    modifier: Modifier = Modifier,
    splitNumber: MutableState<Int>,
    tipAmount: MutableState<Double>,
    totalPerPerson: MutableState<Double>,
    onValueChange: (String) -> Unit,
) {
    var totalBillState = remember {
        mutableStateOf("")
    }
    val validState = remember(key1 = totalBillState.value) {
        totalBillState.value.trim().isNotEmpty()
    }
    val keyboardController = LocalSoftwareKeyboardController.current
    var sliderState = remember {
        mutableStateOf(0.0f)
    }
    val sliderColors = SliderDefaults.colors(
        activeTickColor = Color(0xff2196f3),
        inactiveTickColor = Color(0xff90caf9),
        thumbColor = Color(0xff1e88e5),
        inactiveTrackColor = Color(0xffbbdefb),
        activeTrackColor = Color(0xff64b5f6),
    )
    val tipPercent = (sliderState.value * 100).toInt()
    val total = "%.2f".format(totalPerPerson.value)
    val rippleColor = rememberRipple(color = Color(0xffbbdefb))

    Column(
        verticalArrangement = Arrangement.spacedBy(24.dp),
        modifier = Modifier.padding(vertical = 60.dp, horizontal = 24.dp)
    ) {
        Column(verticalArrangement = Arrangement.spacedBy(6.dp)) {
            Text(text = "Bill total",
                color = Color(0xff858585),
                modifier = Modifier.align(Alignment.Start)
            )
            InputField(
                modifier = modifier.fillMaxWidth(),
                valueState = totalBillState,
                enabled = true,
                isSingleLine = true,
                onActions = KeyboardActions {
                    if (!validState) {
                        return@KeyboardActions
                    }
                    onValueChange(totalBillState.value.trim())
                    keyboardController?.hide()
                }
            ) {
                totalBillState.value = it
                if (it != "") {
                    tipAmount.value = calculateTip(totalBillState.value.toDouble(), tipPercent)
                    totalPerPerson.value =
                        calculateToTalPerson(
                            totalBill = totalBillState.value.toDouble(),
                            splitBy = splitNumber.value,
                            tipPercent = tipPercent
                        )
                } else {
                    tipAmount.value = 0.0
                    totalPerPerson.value = 0.0
                }
            }
        }
        Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
            Text(
                text = "Tip",
                color = Color(0xff858585),
                modifier = Modifier.align(Alignment.Start)
            )
            Text(
                text = "$tipPercent %",
                modifier = Modifier.align(Alignment.Start),
                style = MaterialTheme.typography.displayMedium
            )

            CompositionLocalProvider(LocalIndication provides rippleColor) {
                Slider(
                    value = sliderState.value,
                    onValueChange = { value ->
                        if (validState) {
                            sliderState.value = value
                            tipAmount.value =
                                calculateTip(totalBill = totalBillState.value.toDouble(),
                                    tipPercent)
                            totalPerPerson.value = calculateToTalPerson(
                                totalBill = totalBillState.value.toDouble(),
                                splitBy = splitNumber.value,
                                tipPercent = tipPercent
                            )
                        }
                    },
                    valueRange = 0f..1f,
                    steps = 5,
                    colors = sliderColors,
                    onValueChangeFinished = {}
                )
            }
        }

        Row(
            modifier = Modifier
                .fillMaxWidth()
                .clip(RoundedCornerShape(20.dp))
                .background(color = Color(0xffe3f2fd))
                .padding(vertical = 0.dp, horizontal = 16.dp),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.SpaceAround
        ) {
            Row(verticalAlignment = Alignment.CenterVertically) {
                Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
                    Text(
                        text = "Split",
                        style = MaterialTheme.typography.bodySmall,
                        color = Color(0xff64b5f6)
                    )
                    Row(modifier = Modifier.offset(y = 2.dp), verticalAlignment = Alignment.CenterVertically) {
                        RoundIconButton(
                            imageVector = Icons.Default.Remove,
                            onClick = {
                                if (splitNumber.value > 1) {
                                    splitNumber.value = splitNumber.value - 1
                                }
                                tipAmount.value =
                                    calculateTip(totalBillState.value.toDouble(), tipPercent)
                                totalPerPerson.value = calculateToTalPerson(
                                    totalBill = totalBillState.value.toDouble(),
                                    splitBy = splitNumber.value,
                                    tipPercent = tipPercent
                                )
                            }
                        )
                        Text(
                            text = "${splitNumber.value}",
                            modifier = Modifier
                                .padding(horizontal = 4.dp)
                                .offset(y = -2.dp),
                            style = MaterialTheme.typography.titleMedium,
                            color = Color(0xff2196f3)
                        )
                        RoundIconButton(
                            imageVector = Icons.Default.Add,
                            onClick = {
                                splitNumber.value = splitNumber.value + 1
                                tipAmount.value =
                                    calculateTip(totalBillState.value.toDouble(), tipPercent)
                                totalPerPerson.value = calculateToTalPerson(
                                    totalBill = totalBillState.value.toDouble(),
                                    splitBy = splitNumber.value,
                                    tipPercent = tipPercent
                                )
                            }
                        )
                    }
                }
            }
            Column(
                modifier = Modifier.padding(16.dp),
                verticalArrangement = Arrangement.spacedBy(16.dp),
                horizontalAlignment = Alignment.Start
            ) {
                Text(
                    text = "Total Per Person",
                    style = MaterialTheme.typography.bodySmall,
                    color = Color(0xff64b5f6)
                )
                Text(
                    text = "$${total}",
                    style = MaterialTheme.typography.displayMedium,
                    color = Color(0xff2196f3)
                )
            }
        }
    }
}

@Preview
@Composable
fun InputFieldPreview() {
    InputField()
}

@Composable
fun InputField(
    modifier: Modifier = Modifier,
    valueState: MutableState<String> = remember {
        mutableStateOf("50.00")
    },
    enabled: Boolean = true,
    isSingleLine: Boolean = true,
    keyboardType: KeyboardType = KeyboardType.Number,
    imeAction: ImeAction = ImeAction.Next,
    onActions: KeyboardActions = KeyboardActions.Default,
    onInputChange: (String) -> Unit = {},
) {
    val interactionSource = remember {
        MutableInteractionSource()
    }
    OutlinedTextField(
        value = valueState.value,
        onValueChange = onInputChange,
        modifier = modifier,
        interactionSource = interactionSource,
        leadingIcon = {
            val isFocused = interactionSource.collectIsFocusedAsState()
            Icon(
                imageVector = Icons.Rounded.AttachMoney,
                contentDescription = "Money Icon",
                modifier = Modifier
                    .size(24.dp)
                    .offset(y = 2.dp),
                tint = if (isFocused.value) Color(0xff2196f3) else Color(0xffe3f2fd)
            )
        },
        singleLine = isSingleLine,
        maxLines = 1,
        textStyle = MaterialTheme.typography.titleSmall,
        enabled = enabled,
        keyboardOptions = KeyboardOptions(keyboardType = keyboardType, imeAction = imeAction),
        keyboardActions = onActions,
        placeholder = { Text(text = "0.00") },
        colors = TextFieldDefaults.outlinedTextFieldColors(
            unfocusedBorderColor = Color(0x6d64b5f6),
            focusedBorderColor = Color(0xff1e88e5),
            cursorColor = Color(0xff64b5f6)
        )
    )
}

@Preview
@Composable
fun RoundIconButtonPreview() {
    RoundIconButton(imageVector = Icons.Filled.Add, onClick = {})
}

@Composable
fun RoundIconButton(
    modifier: Modifier = Modifier,
    imageVector: ImageVector,
    onClick: () -> Unit,
    tint: Color = Color(0xff64b5f6),
    backgroundColor: Color = Color(0xd0bbdefb),
    elevation: Dp = 0.dp,
) {
    Card(
        modifier = modifier
            .size(40.dp)
            .clip(CircleShape)
            .clickable { onClick.invoke() }
            .padding(4.dp),
        shape = CircleShape,
        backgroundColor = backgroundColor,
        elevation = elevation
    ) {
        Icon(imageVector = imageVector, contentDescription = "add or subtract icon", tint = tint)
    }
}


fun calculateTip(totalBill: Double, tipPercent: Int): Double {
    return if (totalBill > 1 && totalBill.toString().isNotEmpty()) {
        (totalBill * tipPercent) / 100
    } else {
        return 0.0
    }
}

fun calculateToTalPerson(totalBill: Double, splitBy: Int, tipPercent: Int): Double {
    val bill = calculateTip(totalBill = totalBill, tipPercent = tipPercent) + totalBill
    return bill / splitBy
}